using Microsoft.AspNetCore.Mvc;
using WebRtcProject.Services.Logging;

namespace WebRtcProject.Controllers
{
    [ApiController]
    [Route("api/[controller]")]
    public class LoggingController : ControllerBase
    {
        private readonly ILogResourceManager _logResourceManager;
        private readonly HighPerformanceLogSink _highPerformanceLogSink;
        private readonly ILogger<LoggingController> _logger;

        public LoggingController(
            ILogResourceManager logResourceManager,
            HighPerformanceLogSink highPerformanceLogSink,
            ILogger<LoggingController> logger)
        {
            _logResourceManager = logResourceManager;
            _highPerformanceLogSink = highPerformanceLogSink;
            _logger = logger;
        }

        /// <summary>
        /// 获取日志资源状态
        /// </summary>
        [HttpGet("resource-status")]
        public async Task<ActionResult<LogResourceStatus>> GetResourceStatus()
        {
            try
            {
                var status = await _logResourceManager.GetResourceStatusAsync();
                return Ok(status);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Failed to get log resource status");
                return StatusCode(500, new { error = "Failed to get resource status" });
            }
        }

        /// <summary>
        /// 获取日志性能统计
        /// </summary>
        [HttpGet("performance-stats")]
        public ActionResult<LoggingStatistics> GetPerformanceStats()
        {
            try
            {
                var stats = _highPerformanceLogSink.GetStatistics();
                return Ok(stats);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Failed to get logging performance statistics");
                return StatusCode(500, new { error = "Failed to get performance statistics" });
            }
        }

        /// <summary>
        /// 手动触发日志清理
        /// </summary>
        [HttpPost("cleanup")]
        public async Task<ActionResult> TriggerCleanup()
        {
            try
            {
                await _logResourceManager.CleanupOldLogsAsync();
                return Ok(new { message = "Log cleanup completed successfully", timestamp = DateTime.UtcNow });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Failed to trigger log cleanup");
                return StatusCode(500, new { error = "Failed to trigger cleanup" });
            }
        }

        /// <summary>
        /// 获取当前日志大小
        /// </summary>
        [HttpGet("size")]
        public async Task<ActionResult> GetLogSize()
        {
            try
            {
                var sizeBytes = await _logResourceManager.GetCurrentLogSizeAsync();
                var sizeMB = sizeBytes / 1024.0 / 1024.0;

                return Ok(new
                {
                    sizeBytes,
                    sizeMB = Math.Round(sizeMB, 2),
                    sizeGB = Math.Round(sizeMB / 1024.0, 3),
                    timestamp = DateTime.UtcNow
                });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Failed to get log size");
                return StatusCode(500, new { error = "Failed to get log size" });
            }
        }

        /// <summary>
        /// 检查内存使用情况
        /// </summary>
        [HttpGet("memory-check")]
        public async Task<ActionResult> CheckMemoryUsage()
        {
            try
            {
                var isWithinLimit = await _logResourceManager.CheckMemoryUsageAsync();
                var process = System.Diagnostics.Process.GetCurrentProcess();
                var memoryUsageMB = process.WorkingSet64 / 1024 / 1024;

                return Ok(new
                {
                    isWithinLimit,
                    currentMemoryUsageMB = memoryUsageMB,
                    workingSet = process.WorkingSet64,
                    privateMemorySize = process.PrivateMemorySize64,
                    virtualMemorySize = process.VirtualMemorySize64,
                    timestamp = DateTime.UtcNow
                });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Failed to check memory usage");
                return StatusCode(500, new { error = "Failed to check memory usage" });
            }
        }

        /// <summary>
        /// 获取综合日志健康状况
        /// </summary>
        [HttpGet("health")]
        public async Task<ActionResult> GetLoggingHealth()
        {
            try
            {
                var resourceStatus = await _logResourceManager.GetResourceStatusAsync();
                var performanceStats = _highPerformanceLogSink.GetStatistics();

                var health = new
                {
                    overall = "healthy",
                    timestamp = DateTime.UtcNow,
                    
                    resources = new
                    {
                        memory = new
                        {
                            status = resourceStatus.IsMemoryWithinLimit ? "healthy" : "warning",
                            currentMB = resourceStatus.CurrentMemoryUsageMB,
                            maxMB = resourceStatus.MaxMemoryUsageMB,
                            usagePercentage = resourceStatus.MemoryUsagePercentage
                        },
                        disk = new
                        {
                            status = resourceStatus.IsLogSizeWithinLimit ? "healthy" : "warning",
                            currentMB = resourceStatus.TotalLogSizeMB,
                            maxMB = resourceStatus.MaxLogSizeMB,
                            usagePercentage = resourceStatus.LogSizeUsagePercentage,
                            fileCount = resourceStatus.LogFileCount
                        }
                    },
                    
                    performance = new
                    {
                        totalEvents = performanceStats.TotalLogEvents,
                        droppedEvents = performanceStats.DroppedLogEvents,
                        fastPathEvents = performanceStats.FastPathEvents,
                        eventsPerSecond = Math.Round(performanceStats.EventsPerSecond, 2),
                        dropRate = Math.Round(performanceStats.DropRate, 4),
                        uptime = performanceStats.Uptime.ToString(@"dd\.hh\:mm\:ss")
                    },
                    
                    cleanup = new
                    {
                        lastCleanup = resourceStatus.LastCleanupTime,
                        autoCleanupEnabled = true
                    }
                };

                // 根据资源状态确定整体健康状况
                var overallStatus = "healthy";
                if (!resourceStatus.IsMemoryWithinLimit || !resourceStatus.IsLogSizeWithinLimit)
                {
                    overallStatus = "warning";
                }
                if (performanceStats.DropRate > 10) // 超过10%丢失率认为不健康
                {
                    overallStatus = "critical";
                }

                return Ok(new { overall = overallStatus, details = health });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Failed to get logging health status");
                return StatusCode(500, new { 
                    overall = "error", 
                    error = "Failed to get health status",
                    timestamp = DateTime.UtcNow 
                });
            }
        }

        /// <summary>
        /// 发送测试日志 (用于测试性能)
        /// </summary>
        [HttpPost("test")]
        public ActionResult SendTestLogs([FromBody] TestLogRequest request)
        {
            try
            {
                for (int i = 0; i < request.Count; i++)
                {
                    switch (request.Level.ToLowerInvariant())
                    {
                        case "debug":
                            _logger.LogDebug("Test log message {Index}: {Message}", i, request.Message);
                            break;
                        case "information":
                            _logger.LogInformation("Test log message {Index}: {Message}", i, request.Message);
                            break;
                        case "warning":
                            _logger.LogWarning("Test log message {Index}: {Message}", i, request.Message);
                            break;
                        case "error":
                            _logger.LogError("Test log message {Index}: {Message}", i, request.Message);
                            break;
                        default:
                            _logger.LogInformation("Test log message {Index}: {Message}", i, request.Message);
                            break;
                    }
                }

                return Ok(new
                {
                    message = $"Sent {request.Count} test log messages at {request.Level} level",
                    timestamp = DateTime.UtcNow
                });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Failed to send test logs");
                return StatusCode(500, new { error = "Failed to send test logs" });
            }
        }
    }

    public class TestLogRequest
    {
        public int Count { get; set; } = 10;
        public string Level { get; set; } = "Information";
        public string Message { get; set; } = "This is a test log message for performance testing";
    }
} 